package com.jingbit.ai.helper;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * 压缩工具类
 *
 * @author wellsa
 */
public class CompressHelper {

    private static final String TAG = "CompressHelper";

    /**
     * @param zipFileName
     * @param inputFile
     * @return
     */
    public static boolean compression(String zipFileName, File inputFile) {
        Logger.log(TAG, "compression", "压缩中...");
        try {
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
                    zipFileName));
            BufferedOutputStream bo = new BufferedOutputStream(out);
            doCompression(out, inputFile, inputFile.getName(), bo);
            bo.close();
            out.close(); // 输出流关闭
            Logger.log(TAG, "compression", "压缩成功");
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Logger.log(TAG, "compression err", e);
        } catch (Exception e) {
            e.printStackTrace();
            Logger.log(TAG, "compression err", e);
        }
        Logger.log(TAG, "compression", "压缩失败");
        return false;
    }

    private static void doCompression(ZipOutputStream out, File file, String base,
                                      BufferedOutputStream bo) throws Exception { // 方法重载
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files.length == 0) {
                out.putNextEntry(new ZipEntry(base + "/")); // 创建zip压缩进入点base
            }
            for (int vari = 0; vari < files.length; vari++) {
                doCompression(out, files[vari], base + "/" + files[vari].getName(), bo); // 递归遍历子文件夹
            }
        } else {
            out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入点base
            FileInputStream in = new FileInputStream(file);
            BufferedInputStream bi = new BufferedInputStream(in);
            int b;
            while ((b = bi.read()) != -1) {
                bo.write(b); // 将字节流写入当前zip目录
            }
            bi.close();
            in.close(); // 输入流关闭
        }
    }

    /**
     * 解压文件
     *
     * @param zipfile
     * @param destToPath 输出路径（文件夹目录）
     * @throws IOException
     */
    public static boolean decompression(File zipfile, String destToPath)
            throws IOException {
        Logger.log(TAG, "decompression", zipfile.getName(), destToPath);
        try {
            ZipInputStream zinStream = new ZipInputStream(new FileInputStream(
                    zipfile));// 输入源zip路径
            BufferedInputStream binStream = new BufferedInputStream(zinStream);
            File Fout = null;
            ZipEntry entry;
            try {
                while ((entry = zinStream.getNextEntry()) != null
                        && !entry.isDirectory()) {
                    Fout = new File(destToPath, entry.getName());
                    if (!Fout.exists()) {
                        (new File(Fout.getParent())).mkdirs();
                    }
                    FileOutputStream outStream = new FileOutputStream(Fout);
                    BufferedOutputStream boutStream = new BufferedOutputStream(
                            outStream);
                    int b;
                    while ((b = binStream.read()) != -1) {
                        boutStream.write(b);
                    }
                    boutStream.close();
                    outStream.close();
                }
                Logger.log(TAG, "decompression~", "解压成功");
                binStream.close();
                zinStream.close();
                return true;
            } catch (IOException e) {
                Logger.log(TAG, "decompression err", e);
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Logger.log(TAG, "decompression err", e);
        }
        return false;
    }


    public static String compressImage(String filePath, String targetPath, int quality) {
        Bitmap bm = getSmallBitmap(filePath);//获取一定尺寸的图片
        int degree = readPictureDegree(filePath);//获取相片拍摄角度
        if (degree != 0) {//旋转照片角度，防止头像横着显示
            bm = rotateBitmap(bm, degree);
        }
        File outputFile = new File(targetPath);
        try {
            if (!outputFile.exists()) {
                outputFile.getParentFile().mkdirs();
                //outputFile.createNewFile();
            } else {
                outputFile.delete();
            }
            FileOutputStream out = new FileOutputStream(outputFile);
            bm.compress(Bitmap.CompressFormat.JPEG, quality, out);
        } catch (Exception e) {
        }
        return outputFile.getPath();
    }

    /**
     * 根据路径获得图片信息并按比例压缩，返回bitmap
     */
    public static Bitmap getSmallBitmap(String filePath) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//只解析图片边沿，获取宽高
        BitmapFactory.decodeFile(filePath, options);
        // 计算缩放比
        options.inSampleSize = calculateInSampleSize(options, 480, 800);
        // 完整解析图片返回bitmap
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }


    /**
     * 获取照片角度
     *
     * @param path
     * @return
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转照片
     *
     * @param bitmap
     * @param degress
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
        if (bitmap != null) {
            Matrix m = new Matrix();
            m.postRotate(degress);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), m, true);
            return bitmap;
        }
        return bitmap;
    }

    public static int calculateInSampleSize(BitmapFactory.Options options,
                                            int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

}
